#! /usr/bin/perl

#enable strict mode
use strict;

#use the html subs package adn the DBQueries package
use HTMLSubs;
use DBQueries;
use CGI;
use DBInfoSubs;


#the username of the individual whose profiel shoudl be shown will be passed to this script via get by teh script callign it
#start by obtaining the username
my $input = obtain_input();

#my $input = "username=thomasrantasa&groupSelected=Hello";

#ensure that input is not blank which would mean that the site is illegally accessed
if(length($input) == 0){
	
	#if so, redirect to login
	print CGI -> redirect("login.pl.cgi");
}

#now call the subroutine to decompoe the input into a hash of keys and values
my $ref_input_values = HTMLSubs -> decode_input($input);

#declare username
my $username;

#now call the subroutine to create the main profile
#this subroutine is passed the reference to all information passed to the script so that it can create the profile accordingly
create_profile($ref_input_values);


#main subroutine to display the profile of the user
#this subroutine calls on many other subroutines to generate the actual html code for individual parts of the page
#the hash reference to all passed values is passed to this subroutine so that the correct version of the right profile can be displayed
sub create_profile{
	
	#obtain the parameter
	my $ref_input_values = $_[0];
	
	#dereference
	my %input_values = %$ref_input_values;
	
	#isolate username
	$username = $input_values{'username'};
	
	#now call the subroutine to generate the beginning of the html code
	HTMLSubs -> generate_html_beginning("Welcome $username");
	
	#call the subroutine to handle the main html generation of the profile
	generate_profile_html($ref_input_values);
	
	#lastly call the subroutine the generate the end of the html code
	HTMLSubs -> generate_html_end();
}

#subroutine to generate the main html components of the profile
#this subroutine only creates the outer table and calls on further subs to handle individual content
sub generate_profile_html{
	
	#obtain hash ref from parameters
	$ref_input_values = $_[0];
	
	#dereference the hash
	my %input_values = %$ref_input_values;
	
	$username = $input_values{'username'};
	
	#call sub to print header
	HTMLSubs -> generate_display_head("Your Document Management Profile", "Documents", $username);
	
	#print remaining html code
	print <<END_HTML;
	<!--now proceed to main body-->
	<div class="content">
	<table class="tablecontent">
	<tr class="trmain">
	<td class="tdmain">
	<div class="tdmaindiv">
	
	<!--group information-->
	<h4>Groups</h4>
	<!--separate between owned and member groups-->
END_HTML

	#at this point, call the function to print all the group information
	generate_group_html($input_values{'groupSelected'});
	
	#print more hmtl
	print <<END_HTML;
	</div>
	</td>
	<td class="tdmain">
	<div class="tdmaindiv">
	
	<!--file information-->
	<h4>Files</h4>
	
END_HTML
	
	#at this point, call the function to print all the file information
	generate_file_html($input_values{'groupSelected'}, $input_values{'fileSelected'});
	
	#print more html
	print <<END_HTML;
	
	</div>
	</td>
	<td class="tdmain">
	<div class="tdmaindiv">
	
	<!--specific information-->
	<h4>Content</h4>
END_HTML

	#call function to print specific info
	create_content_html($input_values{'groupSelected'}, $input_values{'fileSelected'});

	#print remainder of profile
	print <<END_HTML;
	</div>
	</td>
	</tr>
	</table>
	</div><!--content-->
	
END_HTML
}

#subroutine to display the content portion of the profile
#this creates and prints the html code for the detailed view of both groups and files
#this sub is passed two parameters, the selected group and the selected file (which can both be blank)
#based on these two parameters the sub decides what action to take further
sub create_content_html{
	
	#obtain parameters
	my $selected_group = $_[0];
	my $selected_file = $_[1];
	
	#if neither file nor group are selected, nothing shoudl be displayed
	if($selected_group eq "" && $selected_file eq ""){
		
		display_user_specifics($username);
	}
	else{
		
		#otherwise specific infomration needs to be displayed so determine if a group or file specific shoudl be displayed
		if($selected_group ne "" && $selected_file eq ""){
		
			#in this case a group is selected but no file
			#therefore display group specific information
			#call sub for that
			display_group_specifics($selected_group);
		}
		
		#otherwise we know that we need to display specific information for a file because the file is selected
		else{
			
			#in this case file specifics need to be displayed
			#therefore display file specific information
			#call sub for that
			display_file_specifics($selected_group, $selected_file);
		}
	
	}
}

#subroutine to display specific information of a user
#this sub will be called by the sub to display specific content
#this is passed one parameter, the name of the user
sub display_user_specifics{
	
	#obtain parameter
	my $username = $_[0];
	
	#call sub to update stats
	DBInfoSubs -> update_user_stats($username);
	
	#now display the information regarding that user
	#obtain info from DB
	#received as array so act accordingly
	my @avg_size = DBQueries::getInfoType($username, "averageFileSize");
	my @avg_word_count = DBQueries::getInfoType($username, "averageWordCount");
	my @avg_word_length = DBQueries::getInfoType($username, "averageWordLength");
	
	#print information
	print <<END_HTML;
	<h5>Detailed Information for $username:</h5>
	<p>Average File Size: $avg_size[0]</p>
	<p>Average Word Count: $avg_word_count[0]</p>
	<p>Average Word Length: $avg_word_length[0]</p>
	<p>The 30 most popular words of your files are:</p>	
	<p>
END_HTML
	
	#obtain most popular words
	my @most_frequent = DBQueries::getInfoTypeValue($username, "topWord") ;
	
	#declare temp var
	my $current_frequent;
	my $loop_counter;
	#loop through the first 30 of these
	#determine correct number of iterations
	if(scalar(@most_frequent) < 30){
		
		if(scalar(DBQueries::getUserFileNames($username)) == 0 ){
			
			$loop_counter = 0;
		}
		else{
			$loop_counter = scalar(@most_frequent);
		}	
	}
	else{
		$loop_counter = 30;
	}
	for(my $i = 0; $i < $loop_counter; $i++){
		
		#ensure exists and print
		if($most_frequent[$i] ne "" || $most_frequent[$i] ne " "){
			
			$current_frequent = $most_frequent[$i];
			
			#substitute delimeter
			$current_frequent =~ s/\.\|><\|\./: /;
			
			print "$current_frequent, ";
		}
	}
	
	#print remaining tags
	print "</p>";
}

#subroutine to display specific information of a file
#this sub will be called by the sub to display specific content
#this is passed one parameter, the name of the file
sub display_file_specifics{
	
	#obtain parameter
	my $group_name = $_[0];
	my $file_name = $_[1];
	
	#declare variable to hold the owner of the file
	my $file_owner;
	
	#find the file_id so that the database can be accessed
	#if no group is selected, the current user is the owner, otherwise make it the group owner
	if($group_name eq ""){
		$file_owner = $username;
	}
	#otherwise the group owner owns the file (it can be that the group and file owner are the same)
	else{
		$file_owner = DBQueries::getGroupOwner($group_name);
	}
	
	#now the id can be found
	my $file_id = DBQueries::getFileID($file_owner, $file_name);
	
	#title
	print "<h5>Detailed Information for $file_name:</h5>";
	
	#obtain info from DB
	#received as array so act accordingly
	my @size = DBQueries::getInfoType($file_id, "fileSize");
	my @word_count = DBQueries::getInfoType($file_id, "wordCount");
	my @avg_word_length = DBQueries::getInfoType($file_id, "avgWordLength");
	
	#print information
	print <<END_HTML;
	
	<p>File Size: $size[0]</p>
	<p>Word Count: $word_count[0]</p>
	<p>Average Word Length: $avg_word_length[0]</p>
	<p>The 30 most popular words of this file are:</p>	
	<p>
END_HTML
	
	#obtain most popular words
	my @most_frequent = DBQueries::getInfoTypeValue($file_id, "keyword") ;
	
	#declare temp var
	my $current_frequent;
	my $loop_counter;
	#loop through the first 30 of these
	#determine correct number of iterations
	if(scalar(@most_frequent) < 30){
		$loop_counter = scalar(@most_frequent);
	}
	else{
		$loop_counter = 30;
	}
	for(my $i = 0; $i < $loop_counter; $i++){
		
		#ensure exists and print
		if($most_frequent[$i] ne "" || $most_frequent[$i] ne " "){
			
			$current_frequent = $most_frequent[$i];
			
			#substitute delimeter
			$current_frequent =~ s/\.\|><\|\./: /;
			
			print "$current_frequent, ";
		}
	}
	
	#print remaining tags
	print "</p>";
	
	#now proceed to handling the buttons depending if the user is the owner or not
	if(DBQueries::isFileOwner($username, $file_id) == 1){
		
	#in this case the user is the owner of the group
		#therefore pritn proper message
		print "<p>You are the owner of this file!</p>";
		
		#now print the horizontal rule and all owner-buttons
		print <<END_HTML;
		<hr />
		<table class="googletablebuttons2" cellpadding="0" cellspacing="0">
			<tr class="googletrbuttons2">
			<td>
END_HTML
			#create hash to contain the username and the file id to pass to the target script of the button
			my %parameter_hash;
			$parameter_hash{'username'} = $username;
			$parameter_hash{'fileID'} = $file_id;
			
			#delete group button
			HTMLSubs -> generate_html_button("deleteFile.pl.cgi", "Delete File", \%parameter_hash);
			
			#manage files button
			print "</td><td>";
			HTMLSubs -> generate_html_button("renameFile.pl.cgi", "Rename File", \%parameter_hash);
				
			#print remainder of tags for owner
			print "</td><td>";
			
			
	}
	#otherwise state that user is member and print code so that the download button common to can be displayed
	else{
		
		print <<END_HTML;
		<p>You are a member of this group!</p>
		<hr />
		<table class="googletablebuttons2" cellpadding="0" cellspacing="0">
			<tr class="googletrbuttons2">
			<td>
END_HTML
		
	}
	
	#now print the last button associated with both owner and user
	#create download file button
	
	#first create a parameter hash for this
	my %parameter_hash;
	$parameter_hash{'username'} = $username;
	
	#add to hash
	$parameter_hash{'fileID'} = $file_id;
	$parameter_hash{'groupName'} = "";
	
	HTMLSubs -> generate_html_button("downloadFiles.pl.cgi", "Download File", \%parameter_hash);
	
	#close the html tags and the content is done
	print "</td></tr></table>";
	
}

#subroutine to display specific information of a group
#this sub will be called by the sub to display specific content
#this is passed one parameter, the name of hte group
sub display_group_specifics{
	
	#obtain parameter
	my $group_name = $_[0];
	
	my $group_owner = DBQueries::getGroupOwner($group_name);
	
	DBInfoSubs -> update_group_stats($group_name);
	
	#title
	print "<h5>Detailed Information:</h5>";
	
	#declare vars to hold infomration from db
	my $file_number = scalar(DBQueries::getGroupFileNames($group_name));
	my $member_number = scalar(DBQueries::getGroupMembers($group_name));
	
	#print basic stats
	print "<p>Name: $group_name</p>";
	print "<p>Files in this group: $file_number</p>";
	print "<p>Members of this group: $member_number</p>";
	
	#obtain info from DB
	#received as array so act accordingly
	my @avg_size = DBQueries::getInfoType($group_owner, $group_name, "averageFileSize");
	my @avg_word_count = DBQueries::getInfoType($group_owner, $group_name, "averageWordCount");
	my @avg_word_length = DBQueries::getInfoType($group_owner, $group_name, "averageWordLength");
	
	#print information
	print <<END_HTML;
	
	<p>Average File Size: $avg_size[0]</p>
	<p>Average Word Count: $avg_word_count[0]</p>
	<p>Average Word Length: $avg_word_length[0]</p>
	<p>The 30 most popular words of the groups files are:</p>	
	<p>
END_HTML
	
	#obtain most popular words
	my @most_frequent = DBQueries::getInfoTypeValue($group_owner, $group_name, "topWord") ;
	
	#declare temp var
	my $current_frequent;
	my $loop_counter;
	#loop through the first 30 of these
	#determine correct number of iterations
	if(scalar(@most_frequent) < 30){
		
		if(scalar(DBQueries::getGroupFileNames($group_name)) == 0 ){
			
			$loop_counter = 0;
		}
		else{
			$loop_counter = scalar(@most_frequent);
		}	
	}
	else{
		$loop_counter = 30;
	}
	for(my $i = 0; $i < $loop_counter; $i++){
		
		#ensure exists and print
		if($most_frequent[$i] ne "" || $most_frequent[$i] ne " "){
			
			$current_frequent = $most_frequent[$i];
			
			#substitute delimeter
			$current_frequent =~ s/\.\|><\|\./: /;
			
			print "$current_frequent, ";
		}
	}
	
	#print remaining tags
	print "</p>";
	
	#now proceed to handling the buttons depending if the user is the owner or not
	if(DBQueries::isGroupOwner($username, $group_name) == 1){
		
		#in this case the user is the owner of the group
		#therefore pritn proper message
		print "<p>You are the owner of this group!</p>";
		
		#now print the horizontal rule and all owner-buttons
		print <<END_HTML;
		<hr />
		<table class="googletablebuttons2" cellpadding="0" cellspacing="0">
			<tr class="googletrbuttons2">
			<td>
END_HTML
			#create hash to contain the username and the group name to pass to the target script of the button
			my %parameter_hash;
			$parameter_hash{'username'} = $username;
			$parameter_hash{'groupName'} = $group_name;
			
			#delete group button
			HTMLSubs -> generate_html_button("deleteGroup.pl.cgi", "Delete Group", \%parameter_hash);
				
			#manage users button
			print "</td><td align=\"center\">";
			HTMLSubs -> generate_html_button("manageGroupUsers.pl.cgi", "Manage Users", \%parameter_hash);
			
			#manage files button
			print "</td><td>";
			HTMLSubs -> generate_html_button("manageGroupFiles.pl.cgi", "Manage Files", \%parameter_hash);
				
			#print remainder of tags for owner
			print "</td></tr><tr class=\"googletrbuttons2\"><td></td><td>";
			
			
	}
	#otherwise state that user is member
	else{
		
		print "<p>You are a member of this group!</p>";
		
		#now create remove form group button for members
		#now print the horizontal rule and all owner-buttons
		print <<END_HTML;
		<hr />
		<table class="googletablebuttons2" cellpadding="0" cellspacing="0">
			<tr class="googletrbuttons2">
			<td>
END_HTML

			#create hash to contain the username and the group name to pass to the target script of the button
			my %parameter_hash;
			$parameter_hash{'username'} = $username;
			$parameter_hash{'groupName'} = $group_name;
			$parameter_hash{'usersToDelete'} = $username;
			
			#remove from group button
			HTMLSubs -> generate_html_button("removeGroupUsers.pl.cgi", "Leave Group", \%parameter_hash);
	}
	
	#now print the last button associated with both owner and user
	#create download all group files button
	
	#first create a parameter hash for this
	my %parameter_hash;
	$parameter_hash{'username'} = $username;
	
	#now obtain the owner of the files so that the file ids can be found
	my $file_owner = DBQueries::getGroupOwner($group_name);
	
	#add to hash
	$parameter_hash{'fileOwner'} = $file_owner;
	$parameter_hash{'groupName'} = $group_name;
	$parameter_hash{'fileName'} = "";
	
	#see if there are files to download
	if(scalar(DBQueries::getGroupFileNames($group_name)) != 0){
		
		#if there are file to download, show enabled button
		HTMLSubs -> generate_html_button("downloadFiles.pl.cgi", "Download all Files", \%parameter_hash);
	}
	#otherwise there are no files

	#close the html tags and the content is done
	print "</td></tr></table>";
}

#subroutine to display the full group information of a user
#this information is split into a separate table of two collums, one for the groups owned and one for the groups joined
sub generate_group_html{
	
	#first obtain the selected group from parameter
	my $selected_group = $_[0];
	my $form_target = $ENV{'SCRIPT_NAME'};
	
	#first obtain all groups that are owned from database
	my @owned_groups = DBQueries::getUserCreatedGroups($username);
	@owned_groups = sort(@owned_groups);
	
	#now obtain all groups the user is a member of
	my @member_groups = DBQueries::getUserGroups($username);
	@member_groups = sort(@member_groups);
	
	print <<END_HTML;
	
	<table>
		<!--titles-->
		<tr>
			<td><p>Groups Owned:</p></td>
			<td><p>Member of:</p></td>
		</tr>
		<tr>
		<!--scroll list for groups owned-->
		<td align="top">
END_HTML

	#make sure that there are owned groups
	if($owned_groups[0] ne "0"){
			
		#print form
		print <<END_HTML;
		<p>
		<form action="$form_target" method=POST>
		<select name="groupSelected" size="10">
	
END_HTML

	#now determine if a group was selected
	if(length($selected_group) != 0){
		
		#make sure the selected group is owned and not just a member of
		if(DBQueries::isGroupOwner($username, $selected_group) == 1){
			
			#in this case we know that an appropriate  group was selected and therefore print the appropriate tag
			print "<OPTION SELECTED>$selected_group";
		}
	}
	
	#declare temp scalar to hold the current group being printed
	my $current_group;
	
	#otherwise just loop through the array of owned groups to display them
	foreach $current_group(@owned_groups){
		
		#unless the current element is the one already selected, print it
		if($current_group eq $selected_group){
			
			#in that case skip
			print "";
		}
		#otherwise print the code for the group
		else{
			print "<OPTION>$current_group";
		}
	}
	
	#now proceed to print the html finished the owned groups submission 
	print <<END_HTML;
	
		</select>
		<!-- now create a hidden field that resubmits the usernmae so that the script knows what user is being passed back-->
		<input type="hidden" name="username" value="$username">
		</p>
		
		<!--submit button-->
		<p>
		<input type="submit" value="View Group"></form>
		</p>
END_HTML
	}
	
	#otherwise print message that no groups are there
	else{
		print"<p>You don't own any gropus currently</p>";
	}
	
		#print member groups
		print <<END_HTML;
		
		<!--now deal with member groups the same way-->
		<td>
END_HTML

	#make sure that there are member groups
	if($member_groups[0] ne "0"){
		
		#print form tags
		print <<END_HTML;
		<p>
		<form action="$form_target" method=POST>
		<select name="groupSelected" size="10">
END_HTML

	#now determine if a group was selected
	if(length($selected_group) != 0){
		
		#make sure the selected group is not owned so that it is not printed doubly
		if(DBQueries::isGroupOwner($username, $selected_group) == 0){
			
			#in this case we know that an appropriate group was selected and therefore print the appropriate tag
			print "<OPTION SELECTED>$selected_group";
		}
		
	}
	
	#declare helper var
	my $current_group;
	
	#otherwise just loop through the array of owned groups to display them
	foreach $current_group(@member_groups){
		
		#unless the current element is the one already selected, print it
		if($current_group eq $selected_group){
			
			#in that case skip
			print "";
		}
		#otherwise print the code for the group
		else{
			print "<OPTION>$current_group";
		}
	}
	
	#now proceed to print the html finished the owned groups submission 
	print <<END_HTML;
	
		</select>
		<!-- now create a hidden field that resubmits the usernmae so that the script knows what user is being passed back-->
		<input type="hidden" name="username" value="$username">
		
		</p>
		
		<!--submit button-->
		<p><input type="submit" value="View Group"></form></p>
		
END_HTML
	}
	#otherwise there are no members
	else{
		#print message accordingly
		print"<p>You are currently not a member of any groups</p>";
	}
	#print final html tags
	print "</tr></table>";
	
}

#subroutine to display the full file information of a user
sub generate_file_html{
	
	#first obtain the selected group and file from parameter
	my $selected_group = $_[0];
	my $selected_file = $_[1];
	my $form_target = $ENV{'SCRIPT_NAME'};
	
	#declare an array to hold the files to be displayed (which ones will be depends on the user-selected parameters)
	my @file_list;
	
	#declare variable to hold teh title of the column (i.e. the name of the user or group whose files are displayed)
	my $collumn_title;
	
	#determine correct title
	if(length($selected_group) != 0){
		$collumn_title = $selected_group;
	}
	#otherwise its the username
	else{
		$collumn_title = $username;
	}
	
	#print the beginning of the scroll list html before it is filled by the part below
	print <<END_HTML;
	
	<table>
		<!--titles-->
		<tr>
			<td><p>Files Of: $collumn_title</p></td>
		</tr>
		<tr>
		<!--scroll list for appropriate files-->
		<td>
END_HTML

	#now determine if a file is selected
	if(length($selected_file) != 0){
		
		#in this case, we select the selected file specified and simply display teh files of the group if the group exists
		if(length($selected_group) != 0){
			
			#since a group was specifically selected, display the files of that group 
			@file_list = DBQueries::getGroupFileNames($selected_group);
		}
		#otherwise no group was selected but a file was so display all files of the user
		else{
			
			#this needs to call the owned and member queries
			@file_list = DBQueries::getUserFileNames($username);
		}
	}
	
	#otherwise do the same without a selected file
	else{
		
		#in this case, we select the selected file specified and simply display teh files of the group if the group exists
		if(length($selected_group) != 0){
			
			#since a group was specifically selected, display the files of that group 
			@file_list = DBQueries::getGroupFileNames($selected_group);
		}
		#otherwise no group was selected but a file was so display all files of the user
		else{
			
			@file_list = DBQueries::getUserFileNames($username);
		}
	}
	
	#make sure that there are files
	if($file_list[0] ne "0"){
		print <<END_HTML;
		<p>
		<form action="$form_target" method=POST>
		<select name="fileSelected" size="10">
END_HTML
	
	#proceed to print the selected file if it exits
	if(length($selected_file) != 0){
		print "<OPTION SELECTED>$selected_file";
	}
		
	#now print the remaining file names in teh array except for the potentially selected file
	#declare temp scalar to help with loop
	my $current_file;
	
	#now loop through array
	foreach $current_file(@file_list){
		
		#unless the current element is the one already selected, print it
		if($current_file eq $selected_file){
			
			#in that case skip
			print "";
		}
		#otherwise print the code for the file
		else{
			print "<OPTION>$current_file";
		}
	}
	
	#now proceed to print the html to finish the file list and selection
	print <<END_HTML;
	
		</select>
		<!-- now create a hidden field that resubmits the usernmae so that the script knows what user is being passed back-->
		<input type="hidden" name="username" value="$username">
		
		<!-- now create a hidden field that resubmits the groupname so that the script knows what group is currently selected-->
		<input type="hidden" name="groupSelected" value="$selected_group">
		
		</p>
		
		<!--submit button-->
		<p><input type="submit" value="View File"></form></p></td></tr>
END_HTML
	}
	#otherwise there are no files to display so show message instead
	else{
		
		print"<p>There are no files in the selected category.</p></td></tr>";
	}

		my %username_hash;
		$username_hash{'username'} = $username;
		
		print "<tr><td>";
		#call subroutine to display button that returns to all user files
		HTMLSubs -> generate_html_button("profile.pl.cgi", "View User Files", \%username_hash);	
		
		print"</td></tr></table>";	
	
}

#subroutine to obtain and determine what information is passed to the script
#to make this more universal, both GET and POST methods are accepted 
#this reads input for both GET and POST
sub obtain_input{

	#declare scalar to hold passed information
	my $input;

	#now retrieve the input through either get or post
	#change the case of request method
	$ENV{'REQUEST_METHOD'} =~ tr/a-z/A-Z/;

	#if post use STDIN
	if ($ENV{'REQUEST_METHOD'} eq "POST"){
		read(STDIN, $input, $ENV{'CONTENT_LENGTH'});

		#exchange plus signs to spaces
		$input =~ s/\+/ /;

		#deal with special characters using the substitution sample provided
		$input =~ s/\%([A-Fa-f0-9]{2})/pack('C', hex($1))/seg;
	}
	#otherwise the env hash
	else{
		$input = $ENV{'QUERY_STRING'};
		
		#exchange plus signs to spaces
		$input =~ s/\+/ /;
		
		#deal with special characters using the substitution sample provided
		$input =~ s/\%([A-Fa-f0-9]{2})/pack('C', hex($1))/seg;
	}
	
	#now return the correct input
	return $input;	
}